package com.yami.shop.multishop.controller;

import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.dto.QrStatisticsList;
import com.yami.shop.bean.model.ProdNft;
import com.yami.shop.bean.model.Product;
import com.yami.shop.bean.model.QrcodeTicket;
import com.yami.shop.bean.model.ReproductionQrcode;
import com.yami.shop.bean.vo.CreatQrVo;
import com.yami.shop.common.annotation.RedisLock;
import com.yami.shop.common.bean.Minio;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.IdUtil;
import com.yami.shop.common.util.OssMultipartFile;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.util.StringUtils;
import com.yami.shop.common.util.pdfUtil.PdfUtils;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.mystery.common.model.ActivityProd;
import com.yami.shop.mystery.common.service.ActivityPresellService;
import com.yami.shop.mystery.common.service.ActivityProdService;
import com.yami.shop.security.common.util.AuthUserContext;
import com.yami.shop.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/shop/reproductionQrcode")
@Tag(name = "复刻画二维码")
@AllArgsConstructor
public class ReproductionQrcodeController {


    private final ReproductionQrcodeService reproductionQrcodeService;

    private final Snowflake snowflake;

    private final QrcodeTicketService qrcodeTicketService;

    private final ProductService productService;

    private final IdUtil idUtil;

    private final SysConfigService sysConfigService;

    @Autowired
    private ShopConfig shopConfig;

    @Autowired
    private ProdNftService prodNftService;
    @Autowired
    private AttachFileService attachFileService;



    @GetMapping("/addOrUpdate")
    @Operation(summary = "生成复刻画二维码" , description = "生成复刻画二维码")
    public ServerResponseEntity<Void> addOrUpdate(Long prodId){
        String fkhUrl = sysConfigService.getValue("fkh_url");
        String copyrightId = sysConfigService.getValue("copyright_id");

        List<ReproductionQrcode> reproductionQrcodes = new ArrayList<>();
        // 获取 商品库存数量
        Product byId = productService.getProductById(prodId);
        // 获取生成 二维码个数
        long qrCount = reproductionQrcodeService.count(new QueryWrapper<ReproductionQrcode>().eq("prod_id", prodId));
        // 获取商品信息
        Product product = productService.getProductById(prodId);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String certificate = getBase64(product, product.getProdId() + "", "daw" + cn.hutool.core.util.IdUtil.simpleUUID(), sdf.format(new Date()));

        // 生成二维码
        for(int i=0;i< byId.getTotalStocks() - qrCount;i++){
            String ticketCode = String.valueOf(snowflake.nextId());
            String ticket = idUtil.nextShortId();
            QrcodeTicket qrcodeTicket = new QrcodeTicket();
            qrcodeTicket.setCreateTime(new Date());
            qrcodeTicket.setType(3);
            qrcodeTicket.setTicket(ticket);
            qrcodeTicket.setTicketUrl(fkhUrl + "&ticketType=4&copyrightId="+copyrightId+"&ticketCode="+ticketCode+"&qrcodeType=authentication&mainProdId="+prodId);
            qrcodeTicketService.save(qrcodeTicket);
            ReproductionQrcode reproductionQrcode = new ReproductionQrcode();
            reproductionQrcode.setQrcodeId(qrcodeTicket.getTicketId());
            reproductionQrcode.setProdId(prodId);
            reproductionQrcode.setStatus("0");
            reproductionQrcode.setQrcodeCode(ticketCode);
            reproductionQrcode.setCertificate(certificate);
            reproductionQrcodes.add(reproductionQrcode);
        }
        // 保存复刻画二维码信息
        if(ObjectUtil.isNotEmpty(reproductionQrcodes)){
            reproductionQrcodeService.saveBatch(reproductionQrcodes);
        }
        return ServerResponseEntity.success();
    }


    @GetMapping("/page")
    @Operation(summary = "分页获取复刻画二维码信息" , description = "分页获取复刻画二维码信息")
    public ServerResponseEntity<IPage<ReproductionQrcode>> getPage(PageParam<ReproductionQrcode> page, ReproductionQrcode param){

        return ServerResponseEntity.success(reproductionQrcodeService.pageData(page, param));
    }

    @GetMapping("/listData")
    @Operation(summary = "复刻画二维码列表" , description = "复刻画二维码列表")
    public ServerResponseEntity<IPage<ReproductionQrcode>> listData(PageParam<ReproductionQrcode> page,Long prodId){


        return ServerResponseEntity.success(reproductionQrcodeService.page(page,new QueryWrapper<ReproductionQrcode>().eq("prod_id",prodId)));
    }

    @GetMapping("/download")
    @Operation(summary = "复刻画二维码下载" , description = "复刻画二维码下载")
    public void download(Long prodId,Long batchId,Long activityId, HttpServletResponse response){
        // 查询二维码信息
        List<QrcodeTicket> qrcodeTicketList = reproductionQrcodeService.listData(prodId,batchId,activityId);
        // 生成二维码文件
        List<File> qrCodeFiles = new ArrayList<>();
        for(QrcodeTicket qrcodeTicket : qrcodeTicketList){
            QrConfig config = new QrConfig(300, 300);
            BufferedImage qrgenerate = QrCodeUtil.generate(qrcodeTicket.getTicketUrl(), config);
            //保存图片
            ByteArrayOutputStream qrOutputStream = new ByteArrayOutputStream();
            //读文件
            try {
                ImageIO.write(qrgenerate, "jpg", qrOutputStream);
                MultipartFile ossMultipartFile = new OssMultipartFile("111.jpg", ".jpg", qrOutputStream.toByteArray());
                File tempFile = FileUtil.createTempFile(".png",true);
                FileUtils.copyInputStreamToFile(ossMultipartFile.getInputStream(),tempFile);
                qrCodeFiles.add(tempFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        File zipTempFile = FileUtil.createTempFile();
        // 打zip包
        if (ObjectUtil.isNotEmpty(qrCodeFiles)) {
            File[] fileArr = qrCodeFiles.toArray(new File[]{});
            ZipUtil.zip(zipTempFile, false, fileArr);
        }
        // 删除临时文件
        qrCodeFiles.forEach(File::delete);
        // 下载
        downloadZip(zipTempFile,response);
    }

    @DeleteMapping("/del/{id}")
    @Operation(summary = "复刻画二维码删除" , description = "复刻画二维码删除")
    public ServerResponseEntity<Void> delModel(@PathVariable("id") Long id){

        return ServerResponseEntity.success();
    }

    @GetMapping("viewQr")
    @Operation(summary = "活动二维码查看" , description = "活动二维码查看")
    public ServerResponseEntity<List<QrStatisticsList>> viewQr(Long activityId){
        // 获取二维码信息
        List<QrStatisticsList> qrStatisticsLists = reproductionQrcodeService.viewQr(AuthUserContext.get().getUserId(), activityId);
        for(QrStatisticsList qrStatisticsList : qrStatisticsLists){
            // 如果二维码数量小于商品原始库存 生成二维码
            if(qrStatisticsList.getProdOriginStocks() > qrStatisticsList.getNum()){
                reproductionQrcodeService.createQr(
                        CreatQrVo.builder()
                                .activityId(qrStatisticsList.getActivityId())
                                .prodId(qrStatisticsList.getProdId())
                                .num(qrStatisticsList.getProdOriginStocks() - qrStatisticsList.getNum())
                                .batchId(qrStatisticsList.getBatchId())
                                .build());
            }
        }
        return ServerResponseEntity.success(qrStatisticsLists);
    }

    public static void downloadZip(File file, HttpServletResponse response) {
        OutputStream toClient = null;
        try {
            // 以流的形式下载文件。
            BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
//            response.reset();
            toClient = new BufferedOutputStream(response.getOutputStream());
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/zip");
            response.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
            toClient.write(buffer);
            toClient.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (toClient != null) {
                try {
                    toClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //删除改临时zip包(此zip包任何时候都不需要保留,因为源文件随时可以再次进行压缩生成zip包)
            file.delete();
        }
    }

    private String getBase64(Product productInfo, String worksNo, String tokenId, String time) {

        try{
            Map<String, Object> keyWordMap = new HashMap<>();

            keyWordMap.put("name","");
            keyWordMap.put("worksNo",worksNo);
            keyWordMap.put("worksTypeName","字画");
            Map<String,String> imageMap = new HashMap<>();

            Minio minio = shopConfig.getMinio();
            keyWordMap.put("worksName",productInfo.getProdName());
            imageMap.put("worksImg",minio.getEndpoint() + "/" + minio.getBucketName() + "/" + productInfo.getPic());
            ProdNft prodNft = prodNftService.getDataByProdId(productInfo.getProdId());
            keyWordMap.put("autherName",prodNft.getAuthorName());
            keyWordMap.put("tokenId","待上链");
            if (StringUtils.isNotEmpty(tokenId)) {
                keyWordMap.put("tokenId",tokenId);
            }
            keyWordMap.put("time","待上链");
            if (StringUtils.isNotEmpty(time)) {
                keyWordMap.put("time",time);
            }

            URL url = new URL(minio.getEndpoint() + "/" + minio.getBucketName() + "/cqdj.pdf");
            URLConnection urlConnection = url.openConnection();
            urlConnection.connect();
            ByteArrayOutputStream qrOutputStream = new ByteArrayOutputStream();
            PdfUtils.generatePdf(urlConnection.getInputStream(), qrOutputStream, keyWordMap,imageMap,35f);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ByteArrayOutputStream scaleOutputStream = new ByteArrayOutputStream();
            //保存图片
            PDDocument document = PDDocument.load(qrOutputStream.toByteArray());
            PDFRenderer pdfRenderer = new PDFRenderer(document);
            BufferedImage image = pdfRenderer.renderImageWithDPI(0, 300); // 使用300dpi解析第一页，可以自行调整dpi大小
            ImageIO.write(image, "JPEG", outputStream);
            MultipartFile ossMultipartFile = new OssMultipartFile("111.jpg", ".jpg", outputStream.toByteArray());
            ImgUtil.scale(ossMultipartFile.getInputStream(),scaleOutputStream,0.1f);

            return attachFileService.uploadFile(scaleOutputStream.toByteArray(), UUID.randomUUID() + ".jpg");
        }catch (Exception e){
            e.printStackTrace();
            return "";
        }
    }

}
